#include "lib/lock.h"
#include "lib/print.h"
#include "dev/timer.h"
#include "memlayout.h"
#include "riscv.h"

/*-------------------- 工作在M-mode --------------------*/

// in trap.S M-mode时钟中断处理流程
extern void timer_vector();

// 每个CPU在时钟中断中需要的临时空间
static uint64 mscratch[NCPU][5];

// 时钟中断间隔
#define INTERVAL 1000000 // 设置适当的间隔时间

// 时钟初始化
// called in start.c
void timer_init() {
    int id = r_mhartid(); // 获取当前 CPU 的 ID

    // 设置 mscratch 的初始值，存储 CLINT_MTIMECMP 地址和 INTERVAL
    mscratch[id][3] = (uint64)CLINT_MTIMECMP(id);
    mscratch[id][4] = INTERVAL;

    // 将 mscratch 数组地址写入 mscratch 寄存器
    w_mscratch((uint64)mscratch[id]);

    // 设置 mtvec 寄存器为 timer_vector 地址
    w_mtvec((uint64)timer_vector);

    // 设置初始的 CLINT_MTIMECMP 值，使中断在 INTERVAL 后触发
    *(uint64*)CLINT_MTIMECMP(id) = r_time() + INTERVAL;

    // 启用 M-mode 的全局中断
    w_mstatus(r_mstatus() | MSTATUS_MIE);

    // 启用 M-mode 的定时器中断
    w_mie(r_mie() | MIE_MTIE);
}

/*--------------------- 工作在S-mode --------------------*/

// 系统时钟
timer_t sys_timer;

// 时钟创建(初始化系统时钟)
void timer_create()
{
    spinlock_init(&sys_timer.lk,"sys_timer");
    sys_timer.ticks = 0;
    // printf("timer_create() is finished\n");
}

// 时钟更新(ticks++)
void  timer_update()
{
    spinlock_acquire(&sys_timer.lk);
    sys_timer.ticks++;
    spinlock_release(&sys_timer.lk);
}

// 返回系统时钟ticks
uint64 timer_get_ticks()
{
    return sys_timer.ticks;
}